home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
os2
/
daytime.zip
/
daytime.c
next >
Wrap
C/C++ Source or Header
|
1997-04-24
|
7KB
|
285 lines
/* daytime.c - set local time from remote daytime or time server
*
* for IBM TCP/IP 2.0 for OS/2
*
* Author: Kai Uwe Rommel <rommel@ars.muc.de>
* Created: Sun Apr 10 1994
*
* This code is in the public domain.
* Let the author know if you make improvements or fixes, though.
*/
static char *rcsid =
"$Id: daytime.c,v 1.8 1996/12/08 11:18:04 rommel Exp rommel $";
static char *rcsrev = "$Revision: 1.8 $";
/*
* $Log: daytime.c,v $
* Revision 1.8 1996/12/08 11:18:04 rommel
* added get_date prototype
*
* Revision 1.7 1996/12/08 11:15:07 rommel
* don't change time within 1 second margin
* from Ewen McNeill <ewen@naos.co.nz>
*
* Revision 1.6 1996/11/29 15:45:00 rommel
* changes (maxadj) from Ewen McNeill <ewen@naos.co.nz>
*
* Revision 1.5 1995/08/20 08:15:10 rommel
* updated for new emx socket library, IBM compiler
* fixed minor bugs
*
* Revision 1.4 1994/07/17 21:13:26 rommel
* fixed usage() display again
*
* Revision 1.3 1994/07/17 21:10:23 rommel
* fixed usage() display
*
* Revision 1.2 1994/07/17 21:07:57 rommel
* added daemon mode, continuously updating local time
*
* Revision 1.1 1994/07/17 20:45:55 rommel
* Initial revision
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <time.h>
#include <string.h>
#ifdef OS2
#ifdef __IBMC__
#define BSD_SELECT
#include <types.h>
#include <sys/select.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef __EMX__
#define psock_errno perror
#define soclose close
#define sock_init() 0
#endif
#endif
typedef enum {TIME = 0, DAYTIME = 1} service;
typedef enum {UDP = 0, TCP = 1} protocol;
time_t get_date(char *p, void *now);
#ifdef OS2
#define INCL_DOS
#include <os2.h>
int stime(time_t *newtime)
{
struct tm *newtm = localtime(newtime);
DATETIME dt;
dt.hours = newtm -> tm_hour;
dt.minutes = newtm -> tm_min;
dt.seconds = newtm -> tm_sec;
dt.hundredths = 0;
dt.day = newtm -> tm_mday;
dt.month = newtm -> tm_mon + 1;
dt.year = newtm -> tm_year + 1900;
dt.weekday = newtm -> tm_wday;
dt.timezone = -1;
return DosSetDateTime(&dt) != 0;
}
#endif
int get_and_set_time(int dont, int port, char *node,
service serv, protocol proto, time_t offs, time_t maxadj)
{
int sock, bytes, size;
struct sockaddr_in server;
struct hostent *host;
struct linger linger;
time_t now;
time_t here;
char buffer[64];
if ((host = gethostbyname(node)) == NULL)
return psock_errno("gethostbyname()"), 1;
server.sin_family = AF_INET;
server.sin_port = port;
server.sin_addr = * (struct in_addr *) (host -> h_addr);
if (proto == TCP)
{
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
return psock_errno("socket(tcp)"), 1;
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("connect()"), 1;
if ((bytes = recv(sock, buffer, sizeof(buffer), 0)) <= 0)
return psock_errno("recv()"), 1;
}
else
{
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
return psock_errno("socket(udp)"), 1;
if (sendto(sock, "", 1, 0,
(struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("sendto()"), 1;
size = sizeof(server);
if ((bytes = recvfrom(sock, buffer, sizeof(buffer), 0,
(struct sockaddr *) &server, &size)) < 0)
psock_errno("recvfrom()");
}
soclose(sock);
if (serv == DAYTIME)
{
buffer[bytes] = 0;
now = get_date(buffer, NULL);
}
else
{
if (bytes != sizeof(now))
return printf("invalid time value received\n"), 1;
else
{
now = * (time_t *) buffer;
now = ntohl(now);
/*
* The time service returns seconds since 1900/01/01 00:00:00 GMT, not
* since 1970 as assumed by Unix time_t values. We need to subtract
* 70 years' worth of seconds. Fortunately, RFC 868 tells us that the
* daytime value 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT.
*/
now -= 2208988800UL;
}
}
if (now <= 0)
return printf("invalid time\n"), 1;
now += offs;
time(&here);
if (maxadj)
if (now < (here - maxadj) || (here + maxadj) < now)
dont = 1; /* Too far off: just report it */
if (abs(now - here) <= 1)
dont = 1;
if (!dont && stime(&now))
return printf("invalid time set request\n"), 1;
printf("time %s %s: (%+ld) %s", dont ? "at" : "set from",
host -> h_name, now - here, ctime(&now));
fflush(stdout);
return 0;
}
int usage(void)
{
printf("\nUsage: daytime [-ndtTU] [-m secs] [-c int] [-p port] host\n"
"\n -n do not set the local clock, display the remote time only"
"\n -c int run continuously, perform action every 'int' seconds"
"\n -o offs adjust the retrieved time by offs seconds before"
"\n setting the local clock"
"\n -m secs Maximum number of seconds to adjust by\n"
"\n -d use the 'daytime' service (port 13)"
"\n -t use the 'time' service (port 37, default)"
"\n -T use the 'tcp' protocol (default)"
"\n -U use the 'udp' protocol"
"\n -p port use nonstandard port number\n");
return 1;
}
int main(int argc, char **argv)
{
int opt, portnum = -1, daytime = 0, dont = 0;
char *host = NULL;
struct servent *port;
service serv = TIME;
protocol proto = TCP;
time_t offset = 0;
int interval = 0;
int maxadj = 0; /* Maximum number of seconds to adjust by
* where 0 = no maximum. EDM, 27/11/96 */
tzset();
if (sock_init())
return psock_errno("sock_init()"), 1;
while ((opt = getopt(argc, argv, "?ndtTUo:p:c:m:")) != EOF)
switch (opt)
{
case 'n':
dont = 1;
break;
case 'd':
serv = DAYTIME;
break;
case 't':
serv = TIME;
break;
case 'T':
proto = TCP;
break;
case 'U':
proto = UDP;
break;
case 'o':
offset = atol(optarg);
break;
case 'p':
portnum = htons(atoi(optarg));
break;
case 'c':
interval = atol(optarg);
break;
case 'm':
maxadj = atol(optarg);
break;
default:
return usage();
}
if (optind == argc)
return usage();
else
host = argv[optind];
if (portnum == -1)
{
if ((port = getservbyname(serv == DAYTIME ? "daytime" : "time",
proto == TCP ? "tcp" : "udp")) == NULL)
return psock_errno("getservbyname()"), 1;
portnum = port -> s_port;
}
if (interval == 0)
return get_and_set_time(dont, portnum, host, serv, proto, offset, maxadj);
for (;;)
{
get_and_set_time(dont, portnum, host, serv, proto, offset, maxadj);
sleep(interval);
}
}
/* end of daytime.c */